home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / tlogo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  50.0 KB  |  1,781 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <GL/glu.h>
  18. #include <GL/glx.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <X11/keysym.h>
  22. #include <string.h>
  23. #include <math.h>
  24. #ifdef unix
  25. #include <sys/times.h>
  26. #include <sys/param.h>
  27. #endif
  28.  
  29. #define    BLACK    0
  30. #define    GRAY    (1 << (indexBits - 1))
  31. #define    WHITE    ((1 << indexBits) - 1)
  32.  
  33. #define PI 3.141592654
  34.  
  35. static int RGBA_SB_attributes[] = {
  36.     GLX_RGBA,
  37.     GLX_ACCUM_RED_SIZE, 1,
  38.     GLX_RED_SIZE, 1,
  39.     GLX_GREEN_SIZE, 1,
  40.     GLX_BLUE_SIZE, 1,
  41.     GLX_DEPTH_SIZE, 1,
  42.     GLX_STENCIL_SIZE, 1,
  43.     None,
  44. };
  45.  
  46. static int RGBA_DB_attributes[] = {
  47.     GLX_RGBA,
  48.     GLX_ACCUM_RED_SIZE, 1,
  49.     GLX_RED_SIZE, 1,
  50.     GLX_GREEN_SIZE, 1,
  51.     GLX_BLUE_SIZE, 1,
  52.     GLX_DOUBLEBUFFER,
  53.     GLX_DEPTH_SIZE, 1,
  54.     GLX_STENCIL_SIZE, 1,
  55.     None,
  56. };
  57.  
  58. static int CI_SB_attributes[] = {
  59.     GLX_DEPTH_SIZE, 1,
  60.     GLX_STENCIL_SIZE, 1,
  61.     None,
  62. };
  63.  
  64. static int CI_DB_attributes[] = {
  65.     GLX_DOUBLEBUFFER,
  66.     GLX_DEPTH_SIZE, 1,
  67.     GLX_STENCIL_SIZE, 1,
  68.     None,
  69. };
  70.  
  71. static Display *dpy;
  72. static Colormap cmap;
  73. static Window window;
  74. static GLint indexBits;
  75. static char *fontName
  76.     = "-adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1";
  77. static long fontBase;
  78. static long fontWidth, fontHeight;
  79.  
  80. static float black[3] = {0.0, 0.0, 0.0};
  81. static float white[3] = {1.0, 1.0, 1.0};
  82. static float gray[3] =  {0.5, 0.5, 0.5};
  83. static float blue[3] =  {0.0, 0.0, 1.0};
  84.  
  85. static long W = 300, H = 300;
  86.  
  87. static float xRotation = 30.0, yRotation = 30.0;
  88. static float zTranslation = -15.0;
  89. static double plane[4] = {1.0, 0.0, -1.0, 0.0};
  90. static GLint colorIndexes[3] = {0, 200, 255};
  91.  
  92. static long singleCylinder;
  93. static long doubleCylinder;
  94. static long elbow, logo;
  95.  
  96. static long imageComponents = 3;
  97. static long dodither = 1;
  98. static long lighting = 1;
  99. static long twoside = 1;
  100. static long depth = 1;
  101. static long fog = 0;
  102. static long rgb = 1;
  103. static long clipPlane = 1;
  104. static long doubleBuffer = 1;
  105. static long clearMask = GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
  106. static long polymode = GL_FRONT_AND_BACK;
  107. static long capping;
  108. static long culling;
  109. static long cullface;
  110. static long texturing;
  111. static long jittering;
  112. static long motionblur;
  113. static long feedbackmode;
  114. #define MAX_FEED    1048576        /* 4 meg worth of floats */
  115. static GLfloat feedbackBuf[MAX_FEED];
  116.  
  117. static long decimation = 1;    /* Decimate image into 1x1 subimages */
  118.  
  119. #define Bl 0x00
  120. #define Wh 0xff
  121. #define    checkImageWidth 8
  122. #define    checkImageHeight 8
  123. static unsigned char checkImage[3*checkImageWidth*checkImageHeight] = {
  124.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  125.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  126.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  127.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  128.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  129.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  130.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  131.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  132. };
  133.  
  134. #define Rd 0xa40000ff
  135. #define Wt 0xffffffff
  136. #define    brickImageWidth 16
  137. #define    brickImageHeight 16
  138. static unsigned long brickImage[brickImageWidth*brickImageHeight] = {
  139.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  140.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  141.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  142.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  143.     Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
  144.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  145.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  146.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  147.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  148.     Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
  149.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  150.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  151.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  152.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  153.     Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
  154.     Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd
  155. };
  156.  
  157. static unsigned char* image = checkImage;
  158. static long imageHeight = checkImageHeight;
  159. static long imageWidth = checkImageWidth;
  160.  
  161. static float decal[] = {
  162.     GL_DECAL,
  163. };
  164. static float modulate[] = {
  165.     GL_MODULATE,
  166. };
  167. static float repeat[] = {
  168.     GL_REPEAT,
  169. };
  170. static float nearest[] = {
  171.     GL_NEAREST,
  172. };
  173.  
  174. static unsigned char stipple[4*32] = {
  175.     0x00, 0x00, 0x00, 0x00,
  176.     0x00, 0x00, 0x00, 0x00,
  177.     0x00, 0x00, 0x00, 0x00,
  178.     0x00, 0x00, 0x00, 0x00,
  179.     0x00, 0x00, 0x00, 0x00,
  180.     0x00, 0x00, 0x00, 0x00,
  181.     0x00, 0x00, 0x00, 0x00,
  182.     0x00, 0x00, 0x00, 0x00,
  183.  
  184.     0x00, 0x0F, 0xF0, 0x00,
  185.     0x00, 0x0F, 0xF0, 0x00,
  186.     0x00, 0x0F, 0xF0, 0x00,
  187.     0x00, 0x0F, 0xF0, 0x00,
  188.     0x00, 0x0F, 0xF0, 0x00,
  189.     0x00, 0x0F, 0xF0, 0x00,
  190.     0x00, 0x0F, 0xF0, 0x00,
  191.     0x00, 0x0F, 0xF0, 0x00,
  192.  
  193.     0x00, 0x0F, 0xF0, 0x00,
  194.     0x00, 0x0F, 0xF0, 0x00,
  195.     0x00, 0x0F, 0xF0, 0x00,
  196.     0x00, 0x0F, 0xF0, 0x00,
  197.     0x00, 0x0F, 0xF0, 0x00,
  198.     0x00, 0x0F, 0xF0, 0x00,
  199.     0x00, 0x0F, 0xF0, 0x00,
  200.     0x00, 0x0F, 0xF0, 0x00,
  201.  
  202.     0x00, 0x00, 0x00, 0x00,
  203.     0x00, 0x00, 0x00, 0x00,
  204.     0x00, 0x00, 0x00, 0x00,
  205.     0x00, 0x00, 0x00, 0x00,
  206.     0x00, 0x00, 0x00, 0x00,
  207.     0x00, 0x00, 0x00, 0x00,
  208.     0x00, 0x00, 0x00, 0x00,
  209.     0x00, 0x00, 0x00, 0x00,
  210. };
  211.  
  212. static float tscp[18][2] = {
  213.     {0.0, 0.0},     {1.0, 0.0},
  214.     {0.0, .125}, {1.0, .125},
  215.     {0.0, .250}, {1.0, .25},
  216.     {0.0, .375}, {1.0, .375},
  217.     {0.0, .50},     {1.0, .50},
  218.     {0.0, .625}, {1.0, .625},
  219.     {0.0, .75},     {1.0, .75},
  220.     {0.0, .875}, {1.0, .875},
  221.     {0.0, 1.0},     {1.0, 1.0},
  222. };
  223.  
  224. static float scp[18][3] = {
  225.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 5.000000},
  226.     {0.707107, 0.707107, 0.000000},    {0.707107, 0.707107, 5.000000},
  227.     {0.000000, 1.000000, 0.000000},    {0.000000, 1.000000, 5.000000},
  228.     {-0.707107, 0.707107, 0.000000},    {-0.707107, 0.707107, 5.000000},
  229.     {-1.000000, 0.000000, 0.000000},    {-1.000000, 0.000000, 5.000000},
  230.     {-0.707107, -0.707107, 0.000000},    {-0.707107, -0.707107, 5.000000},
  231.     {0.000000, -1.000000, 0.000000},    {0.000000, -1.000000, 5.000000},
  232.     {0.707107, -0.707107, 0.000000},    {0.707107, -0.707107, 5.000000},
  233.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 5.000000},
  234. };
  235.  
  236. static float dcp[18][3] = {
  237.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 7.000000},
  238.     {0.707107, 0.707107, 0.000000},    {0.707107, 0.707107, 7.000000},
  239.     {0.000000, 1.000000, 0.000000},    {0.000000, 1.000000, 7.000000},
  240.     {-0.707107, 0.707107, 0.000000},    {-0.707107, 0.707107, 7.000000},
  241.     {-1.000000, 0.000000, 0.000000},    {-1.000000, 0.000000, 7.000000},
  242.     {-0.707107, -0.707107, 0.000000},    {-0.707107, -0.707107, 7.000000},
  243.     {0.000000, -1.000000, 0.000000},    {0.000000, -1.000000, 7.000000},
  244.     {0.707107, -0.707107, 0.000000},    {0.707107, -0.707107, 7.000000},
  245.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 7.000000},
  246. };
  247.  
  248. static float ep[7][9][3] = {
  249.     {
  250.     {1.000000, 0.000000, 0.000000},
  251.     {0.707107, 0.707107, 0.000000},
  252.     {0.000000, 1.000000, 0.000000},
  253.     {-0.707107, 0.707107, 0.000000},
  254.     {-1.000000, 0.000000, 0.000000},
  255.     {-0.707107, -0.707107, 0.000000},
  256.     {0.000000, -1.000000, 0.000000},
  257.     {0.707107, -0.707107, 0.000000},
  258.     {1.000000, 0.000000, 0.000000},
  259.     },
  260.     {
  261.     {1.000000, 0.034074, 0.258819},
  262.     {0.707107, 0.717087, 0.075806},
  263.     {0.000000, 1.000000, 0.000000},
  264.     {-0.707107, 0.717087, 0.075806},
  265.     {-1.000000, 0.034074, 0.258819},
  266.     {-0.707107, -0.648939, 0.441832},
  267.     {0.000000, -0.931852, 0.517638},
  268.     {0.707107, -0.648939, 0.441832},
  269.     {1.000000, 0.034074, 0.258819},
  270.     },
  271.     {
  272.     {1.000000, 0.133975, 0.500000},
  273.     {0.707107, 0.746347, 0.146447},
  274.     {0.000000, 1.000000, 0.000000},
  275.     {-0.707107, 0.746347, 0.146447},
  276.     {-1.000000, 0.133975, 0.500000},
  277.     {-0.707107, -0.478398, 0.853553},
  278.     {0.000000, -0.732051, 1.000000},
  279.     {0.707107, -0.478398, 0.853553},
  280.     {1.000000, 0.133975, 0.500000},
  281.     },
  282.     {
  283.     {1.000000, 0.292893, 0.707107},
  284.     {0.707107, 0.792893, 0.207107},
  285.     {0.000000, 1.000000, 0.000000},
  286.     {-0.707107, 0.792893, 0.207107},
  287.     {-1.000000, 0.292893, 0.707107},
  288.     {-0.707107, -0.207107, 1.207107},
  289.     {0.000000, -0.414214, 1.414214},
  290.     {0.707107, -0.207107, 1.207107},
  291.     {1.000000, 0.292893, 0.707107},
  292.     },
  293.     {
  294.     {1.000000, 0.500000, 0.866025},
  295.     {0.707107, 0.853553, 0.253653},
  296.     {0.000000, 1.000000, 0.000000},
  297.     {-0.707107, 0.853553, 0.253653},
  298.     {-1.000000, 0.500000, 0.866025},
  299.     {-0.707107, 0.146447, 1.478398},
  300.     {0.000000, 0.000000, 1.732051},
  301.     {0.707107, 0.146447, 1.478398},
  302.     {1.000000, 0.500000, 0.866025},
  303.     },
  304.     {
  305.     {1.000000, 0.741181, 0.965926},
  306.     {0.707107, 0.924194, 0.282913},
  307.     {0.000000, 1.000000, 0.000000},
  308.     {-0.707107, 0.924194, 0.282913},
  309.     {-1.000000, 0.741181, 0.965926},
  310.     {-0.707107, 0.558168, 1.648939},
  311.     {0.000000, 0.482362, 1.931852},
  312.     {0.707107, 0.558168, 1.648939},
  313.     {1.000000, 0.741181, 0.965926},
  314.     },
  315.     {
  316.     {1.000000, 1.000000, 1.000000},
  317.     {0.707107, 1.000000, 0.292893},
  318.     {0.000000, 1.000000, 0.000000},
  319.     {-0.707107, 1.000000, 0.292893},
  320.     {-1.000000, 1.000000, 1.000000},
  321.     {-0.707107, 1.000000, 1.707107},
  322.     {0.000000, 1.000000, 2.000000},
  323.     {0.707107, 1.000000, 1.707107},
  324.     {1.000000, 1.000000, 1.000000},
  325.     },
  326. };
  327.  
  328. static float en[7][9][3] = {
  329.     {
  330.     {1.000000, 0.000000, 0.000000},
  331.     {0.707107, 0.707107, 0.000000},
  332.     {0.000000, 1.000000, 0.000000},
  333.     {-0.707107, 0.707107, 0.000000},
  334.     {-1.000000, 0.000000, 0.000000},
  335.     {-0.707107, -0.707107, 0.000000},
  336.     {0.000000, -1.000000, 0.000000},
  337.     {0.707107, -0.707107, 0.000000},
  338.     {1.000000, 0.000000, 0.000000},
  339.     },
  340.     {
  341.     {1.000000, 0.000000, 0.000000},
  342.     {0.707107, 0.683013, -0.183013},
  343.     {0.000000, 0.965926, -0.258819},
  344.     {-0.707107, 0.683013, -0.183013},
  345.     {-1.000000, 0.000000, 0.000000},
  346.     {-0.707107, -0.683013, 0.183013},
  347.     {0.000000, -0.965926, 0.258819},
  348.     {0.707107, -0.683013, 0.183013},
  349.     {1.000000, 0.000000, 0.000000},
  350.     },
  351.     {
  352.     {1.000000, 0.000000, 0.000000},
  353.     {0.707107, 0.612372, -0.353553},
  354.     {0.000000, 0.866025, -0.500000},
  355.     {-0.707107, 0.612372, -0.353553},
  356.     {-1.000000, 0.000000, 0.000000},
  357.     {-0.707107, -0.612372, 0.353553},
  358.     {0.000000, -0.866025, 0.500000},
  359.     {0.707107, -0.612372, 0.353553},
  360.     {1.000000, 0.000000, 0.000000},
  361.     },
  362.     {
  363.     {1.000000, 0.000000, 0.000000},
  364.     {0.707107, 0.612372, -0.500000},
  365.     {0.000000, 0.707107, -0.707107},
  366.     {-0.707107, 0.500000, -0.500000},
  367.     {-1.000000, 0.000000, 0.000000},
  368.     {-0.707107, -0.500000, 0.500000},
  369.     {0.000000, -0.707107, 0.707107},
  370.     {0.707107, -0.500000, 0.500000},
  371.     {1.000000, 0.000000, 0.000000},
  372.     },
  373.     {
  374.     {1.000000, 0.000000, 0.000000},
  375.     {0.707107, 0.353553, -0.612372},
  376.     {0.000000, 0.500000, -0.866025},
  377.     {-0.707107, 0.353553, -0.612372},
  378.     {-1.000000, 0.000000, 0.000000},
  379.     {-0.707107, -0.353553, 0.612372},
  380.     {0.000000, -0.500000, 0.866025},
  381.     {0.707107, -0.353553, 0.612372},
  382.     {1.000000, 0.000000, 0.000000},
  383.     },
  384.     {
  385.     {1.000000, 0.000000, 0.000000},
  386.     {0.707107, 0.183013, -0.683013},
  387.     {0.000000, 0.258819, -0.965926},
  388.     {-0.707107, 0.183013, -0.683013},
  389.     {-1.000000, 0.000000, 0.000000},
  390.     {-0.707107, -0.183013, 0.683013},
  391.     {0.000000, -0.258819, 0.965926},
  392.     {0.707107, -0.183013, 0.683013},
  393.     {1.000000, 0.000000, 0.000000},
  394.     },
  395.     {
  396.     {1.000000, 0.000000, 0.000000},
  397.     {0.707107, 0.000000, -0.707107},
  398.     {0.000000, 0.000000, -1.000000},
  399.     {-0.707107, 0.000000, -0.707107},
  400.     {-1.000000, 0.000000, 0.000000},
  401.     {-0.707107, 0.000000, 0.707107},
  402.     {0.000000, 0.000000, 1.000000},
  403.     {0.707107, 0.000000, 0.707107},
  404.     {1.000000, 0.000000, 0.000000},
  405.     },
  406. };
  407.  
  408. static float tep[7][9][2] = {
  409.     {
  410.     {0,     0.0},
  411.     {0.125, 0.0},
  412.     {0.25,  0.0},
  413.     {0.375, 0.0},
  414.     {0.5,   0.0},
  415.     {0.625, 0.0},
  416.     {0.75,  0.0},
  417.     {0.875, 0.0},
  418.     {1.0,   0.0},
  419.     },
  420.     {
  421.     {0,     0.16667},
  422.     {0.125, 0.16667},
  423.     {0.25,  0.16667},
  424.     {0.375, 0.16667},
  425.     {0.5,   0.16667},
  426.     {0.625, 0.16667},
  427.     {0.75,  0.16667},
  428.     {0.875, 0.16667},
  429.     {1.0,   0.16667},
  430.     },
  431.     {
  432.     {0,     0.33333},
  433.     {0.125, 0.33333},
  434.     {0.25,  0.33333},
  435.     {0.375, 0.33333},
  436.     {0.5,   0.33333},
  437.     {0.625, 0.33333},
  438.     {0.75,  0.33333},
  439.     {0.875, 0.33333},
  440.     {1.0,   0.33333},
  441.     },
  442.     {
  443.     {0,     0.5},
  444.     {0.125, 0.5},
  445.     {0.25,  0.5},
  446.     {0.375, 0.5},
  447.     {0.5,   0.5},
  448.     {0.625, 0.5},
  449.     {0.75,  0.5},
  450.     {0.875, 0.5},
  451.     {1.0,   0.5},
  452.     },
  453.     {
  454.     {0,     0.6667},
  455.     {0.125, 0.6667},
  456.     {0.25,  0.6667},
  457.     {0.375, 0.6667},
  458.     {0.5,   0.6667},
  459.     {0.625, 0.6667},
  460.     {0.75,  0.6667},
  461.     {0.875, 0.6667},
  462.     {1.0,   0.6667},
  463.     },
  464.     {
  465.     {0,     0.83333},
  466.     {0.125, 0.83333},
  467.     {0.25,  0.83333},
  468.     {0.375, 0.83333},
  469.     {0.5,   0.83333},
  470.     {0.625, 0.83333},
  471.     {0.75,  0.83333},
  472.     {0.875, 0.83333},
  473.     {1.0,   0.83333},
  474.     },
  475.     {
  476.     {0,     1.0},
  477.     {0.125, 1.0},
  478.     {0.25,  1.0},
  479.     {0.375, 1.0},
  480.     {0.5,   1.0},
  481.     {0.625, 1.0},
  482.     {0.75,  1.0},
  483.     {0.875, 1.0},
  484.     {1.0,   1.0},
  485.     }
  486. };
  487.  
  488. static void Build_single_cylinder(void)
  489. {
  490.     float st[2];
  491.  
  492.     glNewList(singleCylinder, GL_COMPILE);
  493.     glBegin(GL_TRIANGLE_STRIP);
  494.        glNormal3fv(scp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(scp[0]);
  495.        glNormal3fv(scp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(scp[1]);
  496.        glNormal3fv(scp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(scp[2]);
  497.        glNormal3fv(scp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(scp[3]);
  498.        glNormal3fv(scp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(scp[4]);
  499.        glNormal3fv(scp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(scp[5]);
  500.        glNormal3fv(scp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(scp[6]);
  501.        glNormal3fv(scp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(scp[7]);
  502.        glNormal3fv(scp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(scp[8]);
  503.        glNormal3fv(scp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(scp[9]);
  504.        glNormal3fv(scp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(scp[10]);
  505.        glNormal3fv(scp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(scp[11]);
  506.        glNormal3fv(scp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(scp[12]);
  507.        glNormal3fv(scp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(scp[13]);
  508.        glNormal3fv(scp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(scp[14]);
  509.        glNormal3fv(scp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(scp[15]);
  510.        glNormal3fv(scp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(scp[16]);
  511.        glNormal3fv(scp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(scp[17]);
  512.     glEnd();
  513.     glEndList();
  514. }
  515.  
  516. static void Build_double_cylinder(void)
  517. {
  518.     float st[2];
  519.  
  520.     glNewList(doubleCylinder, GL_COMPILE);
  521.     glBegin(GL_TRIANGLE_STRIP);
  522.     glNormal3fv(dcp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(dcp[0]);
  523.     glNormal3fv(dcp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(dcp[1]);
  524.     glNormal3fv(dcp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(dcp[2]);
  525.     glNormal3fv(dcp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(dcp[3]);
  526.     glNormal3fv(dcp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(dcp[4]);
  527.     glNormal3fv(dcp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(dcp[5]);
  528.     glNormal3fv(dcp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(dcp[6]);
  529.     glNormal3fv(dcp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(dcp[7]);
  530.     glNormal3fv(dcp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(dcp[8]);
  531.     glNormal3fv(dcp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(dcp[9]);
  532.     glNormal3fv(dcp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(dcp[10]);
  533.     glNormal3fv(dcp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(dcp[11]);
  534.     glNormal3fv(dcp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(dcp[12]);
  535.     glNormal3fv(dcp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(dcp[13]);
  536.     glNormal3fv(dcp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(dcp[14]);
  537.     glNormal3fv(dcp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(dcp[15]);
  538.     glNormal3fv(dcp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(dcp[16]);
  539.     glNormal3fv(dcp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(dcp[17]);
  540.     glEnd();
  541.     glEndList();
  542. }
  543.  
  544. static void Build_elbow(void)
  545. {
  546.     float st[2];
  547.  
  548.     glNewList(elbow, GL_COMPILE);
  549.     glBegin(GL_TRIANGLE_STRIP);
  550.     glNormal3fv(en[0][0]); glTexCoord2fv(tep[0][0]); glVertex3fv(ep[0][0]);
  551.     glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
  552.     glNormal3fv(en[0][1]); glTexCoord2fv(tep[0][1]); glVertex3fv(ep[0][1]);
  553.     glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
  554.     glNormal3fv(en[0][2]); glTexCoord2fv(tep[0][2]); glVertex3fv(ep[0][2]);
  555.     glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
  556.     glNormal3fv(en[0][3]); glTexCoord2fv(tep[0][3]); glVertex3fv(ep[0][3]);
  557.     glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
  558.     glNormal3fv(en[0][4]); glTexCoord2fv(tep[0][4]); glVertex3fv(ep[0][4]);
  559.     glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
  560.     glNormal3fv(en[0][5]); glTexCoord2fv(tep[0][5]); glVertex3fv(ep[0][5]);
  561.     glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
  562.     glNormal3fv(en[0][6]); glTexCoord2fv(tep[0][6]); glVertex3fv(ep[0][6]);
  563.     glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
  564.     glNormal3fv(en[0][7]); glTexCoord2fv(tep[0][7]); glVertex3fv(ep[0][7]);
  565.     glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
  566.     glNormal3fv(en[0][8]); glTexCoord2fv(tep[0][8]); glVertex3fv(ep[0][8]);
  567.     glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
  568.     glEnd();
  569.     glBegin(GL_TRIANGLE_STRIP);
  570.     glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
  571.     glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
  572.     glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
  573.     glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
  574.     glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
  575.     glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
  576.     glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
  577.     glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
  578.     glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
  579.     glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
  580.     glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
  581.     glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
  582.     glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
  583.     glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
  584.     glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
  585.     glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
  586.     glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
  587.     glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
  588.     glEnd();
  589.     glBegin(GL_TRIANGLE_STRIP);
  590.     glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
  591.     glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
  592.     glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
  593.     glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
  594.     glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
  595.     glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
  596.     glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
  597.     glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
  598.     glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
  599.     glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
  600.     glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
  601.     glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
  602.     glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
  603.     glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
  604.     glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
  605.     glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
  606.     glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
  607.     glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
  608.     glEnd();
  609.     glBegin(GL_TRIANGLE_STRIP);
  610.     glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
  611.     glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
  612.     glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
  613.     glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
  614.     glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
  615.     glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
  616.     glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
  617.     glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
  618.     glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
  619.     glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
  620.     glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
  621.     glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
  622.     glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
  623.     glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
  624.     glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
  625.     glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
  626.     glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
  627.     glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
  628.     glEnd();
  629.     glBegin(GL_TRIANGLE_STRIP);
  630.     glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
  631.     glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
  632.     glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
  633.     glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
  634.     glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
  635.     glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
  636.     glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
  637.     glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
  638.     glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
  639.     glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
  640.     glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
  641.     glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
  642.     glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
  643.     glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
  644.     glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
  645.     glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
  646.     glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
  647.     glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
  648.     glEnd();
  649.     glBegin(GL_TRIANGLE_STRIP);
  650.     glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
  651.     glNormal3fv(en[6][0]); glTexCoord2fv(tep[6][0]); glVertex3fv(ep[6][0]);
  652.     glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
  653.     glNormal3fv(en[6][1]); glTexCoord2fv(tep[6][1]); glVertex3fv(ep[6][1]);
  654.     glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
  655.     glNormal3fv(en[6][2]); glTexCoord2fv(tep[6][2]); glVertex3fv(ep[6][2]);
  656.     glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
  657.     glNormal3fv(en[6][3]); glTexCoord2fv(tep[6][3]); glVertex3fv(ep[6][3]);
  658.     glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
  659.     glNormal3fv(en[6][4]); glTexCoord2fv(tep[6][4]); glVertex3fv(ep[6][4]);
  660.     glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
  661.     glNormal3fv(en[6][5]); glTexCoord2fv(tep[6][5]); glVertex3fv(ep[6][5]);
  662.     glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
  663.     glNormal3fv(en[6][6]); glTexCoord2fv(tep[6][6]); glVertex3fv(ep[6][6]);
  664.     glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
  665.     glNormal3fv(en[6][7]); glTexCoord2fv(tep[6][7]); glVertex3fv(ep[6][7]);
  666.     glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
  667.     glNormal3fv(en[6][8]); glTexCoord2fv(tep[6][8]); glVertex3fv(ep[6][8]);
  668.     glEnd();
  669.     glEndList();
  670. }
  671.  
  672. static void Bend_forward(void)
  673. {
  674.     glTranslatef(0.0, 1.0, 0.0);
  675.     glRotatef(90.0, 1, 0, 0);
  676.     glTranslatef(0.0, -1.0, 0.0);
  677. }
  678.  
  679. static void Bend_left(void)
  680. {
  681.     glRotatef(-90.0, 0, 0, 1);
  682.     glTranslatef(0.0, 1.0, 0.0);
  683.     glRotatef(90.0, 1, 0, 0);
  684.     glTranslatef(0.0, -1.0, 0.0);
  685. }
  686.  
  687. static void Bend_right(void)
  688. {
  689.     glRotatef(90.0, 0, 0, 1);
  690.     glTranslatef(0.0, 1.0, 0.0);
  691.     glRotatef(90.0, 1, 0, 0);
  692.     glTranslatef(0.0, -1.0, 0.0);
  693. }
  694.  
  695. static void Build_logo(void)
  696. {
  697.     glNewList(logo, GL_COMPILE);
  698.     glTranslatef(5.5, -3.5, 4.5);
  699.     glTranslatef(0.0, 0.0, -7.0);
  700.     glIndexi(GRAY);
  701.     glColor3f(1, 0, 0); 
  702.     glCallList(doubleCylinder);
  703.     Bend_forward();
  704.     glColor3f(0, 1, 0);
  705.     glCallList(elbow);
  706.     glTranslatef(0.0, 0.0, -7.0);
  707.     glColor3f(1, 0, 0);
  708.     glCallList(doubleCylinder);
  709.     Bend_forward();
  710.     glColor3f(0, 1, 0);
  711.     glCallList(elbow);
  712.     glTranslatef(0.0, 0.0, -5.0);
  713.     glColor3f(1, 1, 0);
  714.     glCallList(singleCylinder);
  715.     Bend_right();
  716.     glColor3f(0, 1, 0);
  717.     glCallList(elbow);
  718.     glTranslatef(0.0, 0.0, -7.0);
  719.     glColor3f(1, 0, 0);
  720.     glCallList(doubleCylinder);
  721.     Bend_forward();
  722.     glColor3f(0, 1, 0);
  723.     glCallList(elbow);
  724.     glTranslatef(0.0, 0.0, -7.0);
  725.     glColor3f(1, 0, 0);
  726.     glCallList(doubleCylinder);
  727.     Bend_forward();
  728.     glColor3f(0, 1, 0);
  729.     glCallList(elbow);
  730.     glTranslatef(0.0, 0.0, -5.0);
  731.     glColor3f(1, 1, 0);
  732.     glCallList(singleCylinder);
  733.     Bend_left();
  734.     glColor3f(0, 1, 0);
  735.     glCallList(elbow);
  736.     glTranslatef(0.0, 0.0, -7.0);
  737.     glColor3f(1, 0, 0);
  738.     glCallList(doubleCylinder);
  739.     Bend_forward();
  740.     glColor3f(0, 1, 0);
  741.     glCallList(elbow);
  742.     glTranslatef(0.0, 0.0, -7.0);
  743.     glColor3f(1, 0, 0);
  744.     glCallList(doubleCylinder);
  745.     Bend_forward();
  746.     glColor3f(0, 1, 0);
  747.     glCallList(elbow);
  748.     glTranslatef(0.0, 0.0, -5.0);
  749.     glColor3f(1, 1, 0);
  750.     glCallList(singleCylinder);
  751.     Bend_right();
  752.     glColor3f(0, 1, 0);
  753.     glCallList(elbow);
  754.     glTranslatef(0.0, 0.0, -7.0);
  755.     glColor3f(1, 0, 0);
  756.     glCallList(doubleCylinder);
  757.     Bend_forward();
  758.     glColor3f(0, 1, 0);
  759.     glCallList(elbow);
  760.     glTranslatef(0.0, 0.0, -7.0);
  761.     glColor3f(1, 0, 0);
  762.     glCallList(doubleCylinder);
  763.     Bend_forward();
  764.     glColor3f(0, 1, 0);
  765.     glCallList(elbow);
  766.     glTranslatef(0.0, 0.0, -5.0);
  767.     glColor3f(1, 1, 0);
  768.     glCallList(singleCylinder);
  769.     Bend_left();
  770.     glColor3f(0, 1, 0);
  771.     glCallList(elbow);
  772.     glTranslatef(0.0, 0.0, -7.0);
  773.     glColor3f(1, 0, 0);
  774.     glCallList(doubleCylinder);
  775.     Bend_forward();
  776.     glColor3f(0, 1, 0);
  777.     glCallList(elbow);
  778.     glTranslatef(0.0, 0.0, -7.0);
  779.     glColor3f(1, 0, 0);
  780.     glCallList(doubleCylinder);
  781.     Bend_forward();
  782.     glColor3f(0, 1, 0);
  783.     glCallList(elbow);
  784.     glTranslatef(0.0, 0.0, -5.0);
  785.     glColor3f(1, 1, 0);
  786.     glCallList(singleCylinder);
  787.     Bend_right();
  788.     glColor3f(0, 1, 0);
  789.     glCallList(elbow);
  790.     glTranslatef(0.0, 0.0, -7.0);
  791.     glColor3f(1, 0, 0);
  792.     glCallList(doubleCylinder);
  793.     Bend_forward();
  794.     glColor3f(0, 1, 0);
  795.     glCallList(elbow);
  796.     glTranslatef(0.0, 0.0, -7.0);
  797.     glColor3f(1, 0, 0);
  798.     glCallList(doubleCylinder);
  799.     Bend_forward();
  800.     glColor3f(0, 1, 0);
  801.     glCallList(elbow);
  802.     glTranslatef(0.0, 0.0, -5.0);
  803.     glColor3f(1, 1, 0);
  804.     glCallList(singleCylinder);
  805.     Bend_left();
  806.     glColor3f(0, 1, 0);
  807.     glCallList(elbow);
  808.     glEndList();
  809. }
  810.  
  811. static void Build_lists(void)
  812. {
  813.     singleCylinder = glGenLists(1);
  814.     doubleCylinder = glGenLists(1);
  815.     elbow = glGenLists(1);
  816.     logo = glGenLists(1);
  817.  
  818.     Build_single_cylinder();
  819.     Build_double_cylinder();
  820.     Build_elbow();
  821.     Build_logo();
  822. }
  823.  
  824.  
  825. static void Init(void)
  826. {
  827.     static float ambient[] = {0.1, 0.1, 0.1, 1.0};
  828.     static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
  829.     static float position[] = {90.0, 90.0, 150.0, 0.0};
  830.     static float front_mat_shininess[] = {30.0};
  831.     static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
  832.     static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
  833.     static float back_mat_shininess[] = {50.0};
  834.     static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
  835.     static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
  836.     static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
  837.     static float lmodel_twoside[] = {GL_TRUE};
  838.     
  839.     glFrontFace(GL_CW);
  840.     glEnable(GL_DEPTH_TEST);
  841.     glDepthFunc(GL_LEQUAL);
  842.  
  843.     glMatrixMode(GL_PROJECTION);
  844.     glLoadIdentity();
  845.     gluPerspective(90, 1.0, 1.0, 200.0);
  846.     glMatrixMode(GL_MODELVIEW);
  847.     glClearColor(0.0, 0.0, 0.0, 0.0);
  848.     glClearStencil(0);
  849.     glClearAccum(0,0,0,0);
  850.     glViewport(0, 0, W, H);
  851.  
  852.     glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  853.     glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  854.     glLightfv(GL_LIGHT0, GL_POSITION, position);
  855.     
  856.     glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
  857.     glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
  858.     glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  859.     glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
  860.     glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
  861.     glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  862.  
  863.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  864.     glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  865.  
  866.     glEnable(GL_LIGHTING);
  867.     glEnable(GL_LIGHT0);
  868.     glEnable(GL_CLIP_PLANE0);
  869.  
  870.     if (rgb) {
  871.     static float fog_color[] = {0.0, 0.0, 0.0, 1.0};
  872.  
  873.     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
  874.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  875.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  876.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
  877.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
  878.     glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, checkImageHeight, 0,
  879.              GL_RGB, GL_UNSIGNED_BYTE, checkImage);
  880.     glEnable(GL_TEXTURE_2D);
  881.     texturing = 1;
  882.     glEnable(GL_CULL_FACE);
  883.     culling = 1;
  884.     glCullFace(GL_BACK);
  885.     cullface = GL_BACK;
  886.  
  887.     glFogf(GL_FOG_END, 20.0);
  888.     glFogf(GL_FOG_START, 2.0);
  889.     glFogi(GL_FOG_MODE, GL_LINEAR);
  890.     glFogfv(GL_FOG_COLOR, fog_color);
  891.     }
  892.  
  893.     Build_lists();
  894. }
  895.  
  896. GLfloat newMatrix[16] = {
  897.     1, 0, 0, 0,
  898.     0, 1, 0, 0,
  899.     0, 0, 1, 0,
  900.     0, 0, 0, 1,
  901. };
  902.  
  903. static void xformViewport(int vpx, int vpy, int vpw, int vph)
  904. {
  905.     GLfloat origMatrix[16];
  906.     GLfloat halfwidth, halfheight, xcenter, ycenter;
  907.     int i;
  908.  
  909.     glEnable(GL_SCISSOR_TEST); 
  910.     glScissor(vpx, vpy, vpw, vph);
  911.  
  912.     /*
  913.     ** In the general case, we have to push the viewport out half of the
  914.     ** width of a line and the farthest distance which a DrawPixels or 
  915.     ** consecutive glBitmap calls might move.
  916.     **
  917.     ** For now, we push the viewport out a distance of one because there are
  918.     ** no Bitmap rendering calls in the inner loop, and lines are always a 
  919.     ** width of one.
  920.     */
  921.     for (i=0; i<1; i++) {
  922.     if (vpx > 0) {
  923.         vpx--;
  924.         vpw++;
  925.     }
  926.     if (vpy > 0) {
  927.         vpy--;
  928.         vph++;
  929.     }
  930.     if (vpx + vpw < W) {
  931.         vpw++;
  932.     }
  933.     if (vpy + vph < H) {
  934.         vph++;
  935.     }
  936.     }
  937.  
  938.     glViewport(vpx, vpy, vpw, vph);
  939.  
  940.     glGetFloatv(GL_PROJECTION_MATRIX, origMatrix);
  941.  
  942.     glMatrixMode(GL_PROJECTION);
  943.     glPushMatrix();
  944.  
  945.     glLoadIdentity();
  946.  
  947.     halfwidth = vpw / 2.0;
  948.     halfheight = vph / 2.0;
  949.     xcenter = vpx + halfwidth;
  950.     ycenter = vpy + halfheight;
  951.     newMatrix[0] = 1 / halfwidth;
  952.     newMatrix[5] = 1 / halfheight;
  953.     newMatrix[12] = -xcenter / halfwidth;
  954.     newMatrix[13] = -ycenter / halfheight;
  955.     glMultMatrixf(newMatrix);
  956.  
  957.     newMatrix[0] = W / 2.0;
  958.     newMatrix[5] = H / 2.0;
  959.     newMatrix[12] = W / 2.0;
  960.     newMatrix[13] = H / 2.0;
  961.     glMultMatrixf(newMatrix);
  962.  
  963.     glMultMatrixf(origMatrix);
  964. }
  965.  
  966. static void unxformViewport(int vpx, int vpy, int vpw, int vph)
  967. {
  968.     glDisable(GL_SCISSOR_TEST);
  969.     glViewport(0, 0, W, H);
  970.     glMatrixMode(GL_PROJECTION);
  971.     glPopMatrix();
  972. }
  973.  
  974. static void DrawIt(void)
  975. {
  976.     glMatrixMode(GL_MODELVIEW);
  977.     glPushMatrix();
  978.     glTranslatef(0, 0, zTranslation);
  979.     glRotatef(30.0, 1, 0, 0);
  980.     glRotatef(yRotation, 0, 1, 0);
  981.     glClipPlane(GL_CLIP_PLANE0, plane);
  982.  
  983.     if (decimation == 1) { 
  984.     glCallList(logo);
  985.     } else {
  986.     int i, j;
  987.     int vpx, vpy, vpw, vph;
  988.  
  989.     for (i=decimation-1; i>=0; i--) {
  990.         for (j=0; j<decimation; j++) {
  991.         vpx = i*W/decimation;
  992.         vpw = (i+1)*W/decimation - vpx;
  993.         vpy = j*H/decimation;
  994.         vph = (j+1)*H/decimation - vpy;
  995.  
  996.         if (vpw > 0 && vph > 0) {
  997.             xformViewport(vpx, vpy, vpw, vph);
  998.  
  999.             glMatrixMode(GL_MODELVIEW);
  1000.             glPushMatrix();
  1001.  
  1002.             glCallList(logo);
  1003.  
  1004.             glMatrixMode(GL_MODELVIEW);
  1005.             glPopMatrix();
  1006.  
  1007.             unxformViewport(vpx, vpy, vpw, vph);
  1008.         }
  1009.         }
  1010.     }
  1011.     }
  1012.  
  1013.     glMatrixMode(GL_MODELVIEW);
  1014.     glPopMatrix();
  1015. }
  1016.  
  1017. #define NUM_SAMPLES 6
  1018. static float jitter[NUM_SAMPLES][2] = {
  1019.     0.693609,0.450580, 0.306164,0.949401, 0.041299,0.249607,
  1020.     0.959197,0.750780, 0.693563,0.050253, 0.306169,0.549378,
  1021. };
  1022.  
  1023. void jitterWindow(float x, float y)
  1024. {
  1025.     GLfloat matrix[16];
  1026.  
  1027.     /* Jitter projection matrix */
  1028.     glMatrixMode(GL_PROJECTION);
  1029.     glGetFloatv(GL_PROJECTION_MATRIX, matrix);
  1030.     glLoadIdentity();
  1031.     glTranslatef(2*x/W, 2*y/H, 0);
  1032.     glMultMatrixf(matrix);
  1033. }
  1034.  
  1035. static void feedbackVert(GLint *count, GLint total)
  1036. {
  1037.     int i;
  1038.     int valuesLeft;
  1039.     int valuesNeeded;
  1040.  
  1041.     i = *count;
  1042.     valuesLeft = total-i-1;
  1043.     if (texturing) {
  1044.     valuesNeeded=11;
  1045.     } else {
  1046.     valuesNeeded=7;
  1047.     }
  1048.     /*
  1049.     ** Data stored in feedbackBuf:
  1050.     ** i+1 - location (x,y,z)
  1051.     ** i+4 - color (r,g,b,a)
  1052.     ** i+7 - texture coords (s,t,r,q)
  1053.     */
  1054.     if (valuesLeft >= valuesNeeded) {
  1055.     glColor4fv(feedbackBuf+i+4);
  1056.     if (texturing) {
  1057.         glTexCoord4fv(feedbackBuf+i+8);
  1058.     }
  1059.     glVertex3fv(feedbackBuf+i+1);
  1060.     i += valuesNeeded;
  1061.     } else {
  1062.     i = total;
  1063.     }
  1064.     *count = i;
  1065. }
  1066.  
  1067. static void DoDisplay(void)
  1068. {
  1069.     GLint i, max;
  1070.  
  1071.     if (jittering) max = NUM_SAMPLES;
  1072.     else max = 1;
  1073.  
  1074.     if (jittering) {
  1075.     glClear(GL_ACCUM_BUFFER_BIT);
  1076.     }
  1077.     for (i=0; i<max; i++) {
  1078.     if (jittering) {
  1079.         glMatrixMode(GL_PROJECTION);
  1080.         glPushMatrix();
  1081.         jitterWindow(jitter[i][0]-0.5, jitter[i][1]-0.5);
  1082.     }
  1083.     glClear(clearMask);
  1084.     if (capping) {
  1085.         glStencilFunc(GL_ALWAYS, 1, 1);
  1086.         glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
  1087.     }
  1088.     if (feedbackmode) {
  1089.         if (texturing) {
  1090.         glFeedbackBuffer(MAX_FEED, GL_3D_COLOR_TEXTURE, feedbackBuf);
  1091.         } else {
  1092.         glFeedbackBuffer(MAX_FEED, GL_3D_COLOR, feedbackBuf);
  1093.         }
  1094.         (void) glRenderMode(GL_FEEDBACK);
  1095.     }
  1096.     DrawIt();
  1097.     if (capping) {
  1098.         if (clipPlane) glDisable(GL_CLIP_PLANE0);
  1099.         if (lighting) glDisable(GL_LIGHTING);
  1100.         if (culling) glDisable(GL_CULL_FACE);
  1101.         if (texturing) glDisable(GL_TEXTURE_2D);
  1102.  
  1103.         if (rgb) {
  1104.         glColor3f(1.0,1.0,1.0);
  1105.         } else {
  1106.         glIndexf(7);
  1107.         }
  1108.         glStencilFunc(GL_EQUAL, 1, 1);
  1109.  
  1110.         glMatrixMode(GL_MODELVIEW);
  1111.         glPushMatrix();
  1112.         glTranslatef(0, 0, zTranslation);
  1113.         glRotatef(30.0, 1, 0, 0);
  1114.         glRotatef(yRotation, 0, 1, 0);
  1115.         glBegin(GL_QUADS);
  1116.         glVertex3f( 10,  10,  10+plane[3]);
  1117.         glVertex3f(-10,  10, -10+plane[3]);
  1118.         glVertex3f(-10, -10, -10+plane[3]);
  1119.         glVertex3f( 10, -10,  10+plane[3]);
  1120.         glEnd();
  1121.         glPopMatrix();
  1122.  
  1123.         if (texturing) glEnable(GL_TEXTURE_2D);
  1124.         if (culling) glEnable(GL_CULL_FACE);
  1125.         if (lighting) glEnable(GL_LIGHTING);
  1126.         if (clipPlane) glEnable(GL_CLIP_PLANE0);
  1127.     }
  1128.     if (jittering) {
  1129.         glMatrixMode(GL_PROJECTION);
  1130.         glPopMatrix();
  1131.         glAccum(GL_ACCUM, 1.0/max);
  1132.     }
  1133.     }
  1134.     if (feedbackmode) {
  1135.     GLint things;
  1136.     GLint token;
  1137.     GLint n;
  1138.  
  1139.     things = glRenderMode(GL_RENDER);
  1140.     if (things < 0) things = MAX_FEED;
  1141.  
  1142.     glMatrixMode(GL_PROJECTION);
  1143.     glPushMatrix();
  1144.     glLoadIdentity();
  1145.     glOrtho(0, W, 0, H, 1, -1);
  1146.  
  1147.     if (clipPlane) glDisable(GL_CLIP_PLANE0);
  1148.     if (lighting) glDisable(GL_LIGHTING);
  1149.     if (culling) glDisable(GL_CULL_FACE);
  1150.     if (capping) glDisable(GL_STENCIL_TEST);
  1151.  
  1152.     for (i=0; i<things; i++) {
  1153.         token = feedbackBuf[i];
  1154.         switch(token) {
  1155.           case GL_POLYGON_TOKEN:
  1156.         glBegin(GL_POLYGON);
  1157.         i++;
  1158.         if (i != things) {
  1159.             n = feedbackBuf[i];
  1160.             while (n--) {
  1161.             feedbackVert(&i, things);
  1162.             }
  1163.         }
  1164.         glEnd();
  1165.         break;
  1166.           case GL_LINE_TOKEN:
  1167.           case GL_LINE_RESET_TOKEN:
  1168.         glBegin(GL_LINES);
  1169.         feedbackVert(&i, things);
  1170.         feedbackVert(&i, things);
  1171.         glEnd();
  1172.         break;
  1173.           case GL_POINT_TOKEN:
  1174.         glBegin(GL_POINTS);
  1175.         feedbackVert(&i, things);
  1176.         glEnd();
  1177.         break;
  1178.           default:
  1179.             printf("%9.2f?\n", feedbackBuf[i]);
  1180.             break;
  1181.         }
  1182.     }
  1183.  
  1184.     if (capping) glEnable(GL_STENCIL_TEST);
  1185.     if (culling) glEnable(GL_CULL_FACE);
  1186.     if (lighting) glEnable(GL_LIGHTING);
  1187.     if (clipPlane) glEnable(GL_CLIP_PLANE0);
  1188.  
  1189.     glMatrixMode(GL_MODELVIEW);
  1190.     glPushMatrix();
  1191.     glLoadIdentity();
  1192.  
  1193.     glPopMatrix();
  1194.  
  1195.     glMatrixMode(GL_PROJECTION);
  1196.     glPopMatrix();
  1197.     }
  1198.     if (motionblur) {
  1199.     glAccum(GL_MULT, 0.7);
  1200.     glAccum(GL_ACCUM, 0.3);
  1201.     }
  1202.     if (jittering || motionblur) {
  1203.     glAccum(GL_RETURN, 1.0);
  1204.     }
  1205.     glFinish();
  1206. }
  1207.  
  1208. static void SetAntiAliasedGrayScale(void)
  1209. {
  1210.     XColor *xc;
  1211.     float color;
  1212.     long i, j, cells;
  1213.  
  1214.     if (indexBits < 8) return;
  1215.  
  1216.     cells = 1 << indexBits;
  1217.     xc = (XColor *) malloc(cells * sizeof(XColor));
  1218.  
  1219.     for (i = 0; i < 16; i++) {
  1220.     color = (2 * i + 1) / 32.0;
  1221.     for (j = 0; j < 16; j++) {
  1222.         xc[i].pixel = i * 16 + j;
  1223.         xc[i].red = (color * j / 15.0) * 65535.0;
  1224.         xc[i].green = xc[i].red;
  1225.         xc[i].blue = xc[i].red;
  1226.         xc[i].flags = DoRed | DoGreen | DoBlue;
  1227.     }
  1228.     }
  1229.     XStoreColors(dpy, cmap, xc, cells);
  1230.  
  1231.     free((void *) xc);
  1232. }
  1233.  
  1234. static void SetGrayRamp(void)
  1235. {
  1236.     XColor *xc;
  1237.     float color;
  1238.     long i, cells;
  1239.  
  1240.     cells = 1 << indexBits;
  1241.     xc = (XColor *) malloc(cells * sizeof(XColor));
  1242.  
  1243.     for (i = 0; i < cells; i++) {
  1244.     xc[i].pixel = i;
  1245.     xc[i].red = ((float)i / (float)(cells - 1)) * 65535.0;
  1246.     xc[i].green = xc[i].red;
  1247.     xc[i].blue = xc[i].red;
  1248.     xc[i].flags = DoRed | DoGreen | DoBlue;
  1249.     }
  1250.     XStoreColors(dpy, cmap, xc, cells);
  1251.  
  1252.     free((void *) xc);
  1253. }
  1254.  
  1255. static void Usage(void)
  1256. {
  1257.     printf("Usage: tlogo [-c] [-s] [-f xfont] [-geometry WxH+X+Y\n");
  1258.     printf("   -c:  Run in color index mode\n");
  1259.     printf("   -s:  Run in single buffered mode\n");
  1260.     printf("   -f:  Choose a new X font to use\n");
  1261.     printf("   -geometry:  specify window size and location\n");
  1262.     exit(-1);
  1263. }
  1264.  
  1265. static void LoadFont(const char *fontName)
  1266. {
  1267.     XFontStruct *fontInfo;
  1268.     unsigned long first, last;
  1269.  
  1270.     /* Lookup font */
  1271.     fontInfo = XLoadQueryFont(dpy, fontName);
  1272.     if (fontInfo == NULL) {
  1273.     fprintf(stderr, "Can't find font \"%s\"\n", fontName);
  1274.     return;
  1275.     }
  1276.  
  1277.     first = fontInfo->min_char_or_byte2;
  1278.     last = fontInfo->max_char_or_byte2;
  1279.  
  1280.     fontBase = glGenLists(last+1);
  1281.     if (fontBase == 0) {
  1282.     fprintf(stderr, "Out of list space\n");
  1283.     return;
  1284.     }
  1285.     glXUseXFont(fontInfo->fid, first, last-first+1, fontBase+first);
  1286.     fontWidth = fontInfo->max_bounds.width;
  1287.     fontHeight = fontInfo->ascent + fontInfo->descent;
  1288. }
  1289.  
  1290. static void ShowFrames(double start, double stop)
  1291. {
  1292.     char buf[20];
  1293.     sprintf(buf, "%4.1f frames/sec", 1.0 / (stop - start));
  1294.  
  1295.     glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT);
  1296.     glMatrixMode(GL_MODELVIEW);
  1297.     glPushMatrix();
  1298.     glLoadIdentity();
  1299.     glMatrixMode(GL_PROJECTION);
  1300.     glPushMatrix();
  1301.     glLoadIdentity();
  1302.     glOrtho(-0.5, W - 0.5, -0.5, H - 0.5, -1, 1);
  1303.  
  1304.     glDisable(GL_LIGHTING);
  1305.     glDisable(GL_TEXTURE_2D);
  1306.     glDisable(GL_FOG);
  1307.     glDisable(GL_DEPTH_TEST);
  1308.     glDisable(GL_CLIP_PLANE0);
  1309.  
  1310.     glColor3f(1, 1, 1); glIndexi(WHITE);
  1311.     glRasterPos2f(10, fontHeight + 10);
  1312.     glListBase(fontBase);
  1313.     glCallLists(strlen(buf), GL_UNSIGNED_BYTE, buf);
  1314.  
  1315.     glPopMatrix();
  1316.     glMatrixMode(GL_MODELVIEW);
  1317.     glPopMatrix();
  1318.  
  1319.     glPopAttrib();
  1320. }
  1321.  
  1322. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  1323. {
  1324.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  1325.     return GL_TRUE;
  1326.     }
  1327.     return GL_FALSE;
  1328. }
  1329.  
  1330. double Now(void)
  1331. {
  1332. #ifdef __unix
  1333.     struct tms tm;
  1334.     long clk;
  1335.  
  1336.     clk = times(&tm);
  1337.     return (double)clk / (double)HZ;
  1338. #else
  1339.     return 0;
  1340. #endif
  1341. }
  1342.  
  1343. int main(int argc, char** argv)
  1344. {
  1345.     int *attrs, i, rv;
  1346.     XVisualInfo *vi;
  1347.     XSetWindowAttributes swa;
  1348.     XSizeHints sizehints;
  1349.     XEvent ev;
  1350.     GLXContext cx;
  1351.     GLboolean needDisplay = 1;
  1352.     KeySym ks;
  1353.     char buf[10];
  1354.     GLboolean animate = GL_FALSE;
  1355.     GLboolean showFrames = GL_FALSE;
  1356.     char *geometry = NULL;
  1357.     double start;
  1358.  
  1359.     rgb = 1;
  1360.     doubleBuffer = 1;
  1361.  
  1362.     for (i = 1; i < argc; i++) {
  1363.     if (!strcmp(argv[i], "-geometry")) {
  1364.         i++;
  1365.         geometry = argv[i];
  1366.         if (geometry == NULL) {
  1367.         Usage();
  1368.         }
  1369.     } else if (argv[i][0] == '-') {
  1370.         switch (argv[i][1]) {
  1371.           case 'c':
  1372.         rgb = 0;
  1373.         break;
  1374.           case 's':
  1375.         doubleBuffer = 0;
  1376.         break;
  1377.           case 'f':
  1378.         if (i == argc - 1) {
  1379.             Usage();
  1380.         }
  1381.         fontName = argv[++i];
  1382.         break;
  1383.           default:
  1384.         Usage();
  1385.         }
  1386.     } else {
  1387.         Usage();
  1388.     }
  1389.     }
  1390.  
  1391.     if (doubleBuffer) {
  1392.     if (rgb) {
  1393.         attrs = RGBA_DB_attributes;
  1394.     } else {
  1395.         attrs = CI_DB_attributes;
  1396.     }
  1397.     } else {
  1398.     if (rgb) {
  1399.         attrs = RGBA_SB_attributes;
  1400.     } else {
  1401.         attrs = CI_SB_attributes;
  1402.     }
  1403.     }
  1404.  
  1405.     dpy = XOpenDisplay(0);
  1406.     if (!dpy) {
  1407.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  1408.     return -1;
  1409.     }
  1410.  
  1411.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrs);
  1412.     if (!vi) {
  1413.     fprintf(stderr, "No matching visual on \"%s\"\n",
  1414.         getenv("DISPLAY"));
  1415.     return -1;
  1416.     }
  1417.  
  1418.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  1419.                rgb ? AllocNone : AllocAll);
  1420.     sizehints.flags = PPosition | PSize;
  1421.     sizehints.width = W;
  1422.     sizehints.height = H;
  1423.     sizehints.x = 10;
  1424.     sizehints.y = 10;
  1425.     if(geometry) {
  1426.     int flags, x, y, width, height;
  1427.  
  1428.     flags = XParseGeometry(geometry, &x, &y,
  1429.                    (unsigned int *)&width,
  1430.                    (unsigned int *)&height);
  1431.         if(WidthValue & flags) {
  1432.         sizehints.flags |= USSize;
  1433.         sizehints.width = width;
  1434.         W = width;
  1435.     }
  1436.     if(HeightValue & flags) {
  1437.         sizehints.flags |= USSize;
  1438.         sizehints.height = height;
  1439.         H = height;
  1440.     }
  1441.     if(XValue & flags) {
  1442.         if(XNegative & flags)
  1443.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  1444.             - sizehints.width;
  1445.             sizehints.flags |= USPosition;
  1446.         sizehints.x = x;
  1447.     }
  1448.     if(YValue & flags) {
  1449.         if(YNegative & flags)
  1450.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y 
  1451.             - sizehints.height;
  1452.             sizehints.flags |= USPosition;
  1453.         sizehints.y = y;
  1454.     }
  1455.     }
  1456.     swa.border_pixel = 0;
  1457.     swa.colormap = cmap;
  1458.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask;
  1459.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
  1460.                            sizehints.x, sizehints.y,
  1461.                sizehints.width, sizehints.height,
  1462.                0, vi->depth, InputOutput, vi->visual,
  1463.                CWBorderPixel|CWColormap|CWEventMask, &swa);
  1464.     XSetStandardProperties(dpy, window, "tlogo test", "tlogo", None,
  1465.                            argv, argc, &sizehints);
  1466.     XSetWMColormapWindows(dpy, window, &window, 1);
  1467.     XMapWindow(dpy, window);
  1468.     XIfEvent(dpy, &ev, WaitForMapNotify, (char*)window);
  1469.  
  1470.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  1471.     if (!glXMakeCurrent(dpy, window, cx)) {
  1472.     fprintf(stderr, "Can't make window current to context\n");
  1473.     return -1;
  1474.     }
  1475.  
  1476.     if (!rgb) {
  1477.     glGetIntegerv(GL_INDEX_BITS, &indexBits);
  1478.     SetGrayRamp();
  1479.     colorIndexes[0] = BLACK;
  1480.     colorIndexes[1] = GRAY;
  1481.     colorIndexes[2] = WHITE;
  1482.     glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes);
  1483.     }
  1484.  
  1485.     Init();
  1486.     LoadFont(fontName);
  1487.  
  1488.     for (;;) {
  1489.     while (XPending(dpy) != 0) {
  1490.         XNextEvent(dpy, &ev);
  1491.         switch (ev.type) {
  1492.           case Expose:
  1493.         needDisplay = GL_TRUE;
  1494.         break;
  1495.           case ConfigureNotify:
  1496.         W = ev.xconfigure.width;
  1497.         H = ev.xconfigure.height;
  1498.         glViewport(0, 0, W, H);
  1499.         needDisplay = GL_TRUE;
  1500.         break;
  1501.           case KeyPress:
  1502.         rv = XLookupString(&ev.xkey, buf, sizeof(buf), &ks, 0);
  1503.         needDisplay = GL_TRUE;
  1504.         switch (ks) {
  1505.           case XK_Escape:
  1506.             glXDestroyContext(dpy, cx);
  1507.             XCloseDisplay(dpy);
  1508.             return 0;
  1509.           case XK_space:
  1510.             animate = !animate;
  1511.             break;
  1512.           case XK_question:
  1513.             showFrames = !showFrames;
  1514.             break;
  1515.  
  1516.           case XK_Left:
  1517.             yRotation += 0.5;
  1518.             break;
  1519.           case XK_Right:
  1520.             yRotation -= 0.5;
  1521.             break;
  1522.           case XK_Up:
  1523.             plane[3] += 2.0;
  1524.             break;
  1525.           case XK_Down:
  1526.             plane[3] -= 2.0;
  1527.             break;
  1528.           case XK_Z:
  1529.             zTranslation -= 1.0;
  1530.             break;
  1531.           case XK_z:
  1532.             zTranslation += 1.0;
  1533.             break;
  1534.  
  1535.           case XK_1:
  1536.             glPolygonMode(polymode, GL_FILL);
  1537.             break;
  1538.           case XK_2:
  1539.             glPolygonMode(polymode, GL_POINT);
  1540.             break;
  1541.           case XK_3:
  1542.             glPolygonMode(polymode, GL_LINE);
  1543.             break;
  1544.           case XK_p: case XK_P:
  1545.             needDisplay = GL_FALSE;
  1546.             switch (polymode) {
  1547.               case GL_BACK:
  1548.             polymode = GL_FRONT;
  1549.             printf("Polymode now GL_FRONT\n");
  1550.             break;
  1551.               case GL_FRONT:
  1552.             polymode = GL_FRONT_AND_BACK;
  1553.             printf("Polymode now GL_FRONT_AND_BACK\n");
  1554.             break;
  1555.               case GL_FRONT_AND_BACK:
  1556.             polymode = GL_BACK;
  1557.             printf("Polymode now GL_BACK\n");
  1558.             break;
  1559.             }
  1560.             break;
  1561.  
  1562.           case XK_4:
  1563.             glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  1564.             break;
  1565.           case XK_5:
  1566.             glEnable(GL_POLYGON_SMOOTH);
  1567.             if (rgb) {
  1568.             glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  1569.             glEnable(GL_BLEND);
  1570.             glDisable(GL_DEPTH_TEST);
  1571.             } else {
  1572.             SetAntiAliasedGrayScale();
  1573.             }
  1574.             break;
  1575.           case XK_6:
  1576.             glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  1577.             glDisable(GL_POLYGON_SMOOTH);
  1578.             if (rgb) {
  1579.             glBlendFunc(GL_ONE, GL_ZERO);
  1580.             glDisable(GL_BLEND);
  1581.             glEnable(GL_DEPTH_TEST);
  1582.             } else {
  1583.             SetGrayRamp();
  1584.             }
  1585.             break;
  1586.  
  1587.           case XK_7:
  1588.             glPolygonStipple(stipple);
  1589.             glEnable(GL_POLYGON_STIPPLE);
  1590.             break;
  1591.           case XK_8:
  1592.             glDisable(GL_POLYGON_STIPPLE);
  1593.             break;
  1594.  
  1595.           case XK_9:
  1596.             glShadeModel(GL_FLAT);
  1597.             break;
  1598.           case XK_0:
  1599.             glShadeModel(GL_SMOOTH);
  1600.             break;
  1601.  
  1602.           case XK_Q: 
  1603.             glEnable(GL_CULL_FACE);
  1604.             culling = 1;
  1605.             glCullFace(GL_FRONT_AND_BACK);
  1606.             cullface = GL_FRONT_AND_BACK;
  1607.             break;
  1608.           case XK_q:
  1609.             glDisable(GL_CULL_FACE);
  1610.             culling = 0;
  1611.             break;
  1612.           case XK_W: case XK_w:
  1613.             glEnable(GL_CULL_FACE);
  1614.             culling = 1;
  1615.             glCullFace(GL_FRONT);
  1616.             cullface = GL_FRONT;
  1617.             break;
  1618.           case XK_E: case XK_e:
  1619.             glEnable(GL_CULL_FACE);
  1620.             culling = 1;
  1621.             glCullFace(GL_BACK);
  1622.             cullface = GL_BACK;
  1623.             break;
  1624.  
  1625.           case XK_R: case XK_r:
  1626.             glFrontFace(GL_CW);
  1627.             break;
  1628.           case XK_T: case XK_t: 
  1629.             glFrontFace(GL_CCW);
  1630.             break;
  1631.           case XK_Y: case XK_y:
  1632.             glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  1633.             glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
  1634.             glPolygonStipple(stipple);
  1635.             break;
  1636.           case XK_U: case XK_u:
  1637.             glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  1638.             glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
  1639.             glPolygonStipple(stipple);
  1640.             break;
  1641.  
  1642.           case XK_A: case XK_a:
  1643.             glEnable(GL_TEXTURE_2D);
  1644.             texturing = 1;
  1645.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  1646.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  1647.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  1648.                      nearest);
  1649.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  1650.                      nearest);
  1651.             glTexImage2D(GL_TEXTURE_2D, 0, 4, brickImageWidth,
  1652.                  brickImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  1653.                  (const unsigned char*) brickImage);
  1654.             break;
  1655.           case XK_S: case XK_s:
  1656.             glEnable(GL_TEXTURE_2D);
  1657.             texturing = 1;
  1658.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  1659.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  1660.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  1661.                      nearest);
  1662.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  1663.                      nearest);
  1664.             glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
  1665.                  checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
  1666.                  (const unsigned char*) checkImage);
  1667.             break;
  1668.           case XK_D: case XK_d:
  1669.             glDisable(GL_TEXTURE_2D);
  1670.             texturing = 0;
  1671.             break;
  1672.  
  1673.           case XK_F: case XK_f:
  1674.             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
  1675.             break;
  1676.           case XK_G: case XK_g:
  1677.             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, modulate);
  1678.             break;
  1679.  
  1680.           case XK_H: case XK_h:
  1681.             dodither = !dodither;
  1682.             dodither ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
  1683.             break;
  1684.  
  1685.           case XK_L: case XK_l:
  1686.             lighting = !lighting;
  1687.             lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
  1688.             break;
  1689.  
  1690.           case XK_K: case XK_k:
  1691.             twoside = !twoside;
  1692.             glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, twoside);
  1693.             break;
  1694.  
  1695.           case XK_I: case XK_i:
  1696.             fog = !fog;
  1697.             fog ? glEnable(GL_FOG) : glDisable(GL_FOG);
  1698.             break;
  1699.           case XK_J: case XK_j:
  1700.             depth = !depth;
  1701.             if (depth) {
  1702.             glEnable(GL_DEPTH_TEST);
  1703.             clearMask |= GL_DEPTH_BUFFER_BIT;
  1704.             } else {
  1705.             glDisable(GL_DEPTH_TEST);
  1706.             clearMask &= ~GL_DEPTH_BUFFER_BIT;
  1707.             }
  1708.             break;
  1709.  
  1710.           case XK_X: case XK_x:
  1711.             clipPlane = !clipPlane;
  1712.             if (clipPlane)
  1713.             glEnable(GL_CLIP_PLANE0);
  1714.             else
  1715.             glDisable(GL_CLIP_PLANE0);
  1716.             break;
  1717.           case XK_C: case XK_c:
  1718.             capping = !capping;
  1719.             if (capping) {
  1720.             clearMask |= GL_STENCIL_BUFFER_BIT;
  1721.             glEnable(GL_STENCIL_TEST);
  1722.             } else {
  1723.             clearMask &= ~GL_STENCIL_BUFFER_BIT;
  1724.             glDisable(GL_STENCIL_TEST);
  1725.             }
  1726.             break;
  1727.           case XK_V: case XK_v:
  1728.             jittering = 1-jittering;
  1729.             if (motionblur) motionblur = 0;
  1730.             if (feedbackmode) feedbackmode = 0;
  1731.             break;
  1732.           case XK_B: case XK_b:
  1733.             motionblur = 1-motionblur;
  1734.             if (motionblur) {
  1735.             glClear(GL_ACCUM_BUFFER_BIT);
  1736.             }
  1737.             if (jittering) jittering = 0;
  1738.             break;
  1739.           case XK_N: case XK_n:
  1740.             feedbackmode = 1-feedbackmode;
  1741.             if (jittering) jittering = 0;
  1742.             break;
  1743.           case XK_M: 
  1744.             decimation--;
  1745.             if (decimation < 1) decimation = 1;
  1746.             break;
  1747.           case XK_m:
  1748.             decimation++;
  1749.             break;
  1750.           default:
  1751.             needDisplay = GL_FALSE;
  1752.             break;
  1753.         }
  1754.         break;
  1755.         }
  1756.     }
  1757.  
  1758.     if (needDisplay || animate) {
  1759.         if (animate) {
  1760.         yRotation += 0.5;
  1761.         }
  1762.         if (showFrames) {
  1763.         start = Now();
  1764.         }
  1765.         DoDisplay();
  1766.         if (doubleBuffer) {
  1767.         glXSwapBuffers(dpy, window);
  1768.         }
  1769.         if (showFrames) {
  1770.         if (doubleBuffer) glDrawBuffer(GL_FRONT);
  1771.         ShowFrames(start, Now());
  1772.         if (doubleBuffer) glDrawBuffer(GL_BACK);
  1773.         }
  1774.         needDisplay = GL_FALSE;
  1775.     }
  1776.     if (!animate) {
  1777.         XPeekEvent(dpy, &ev);
  1778.     }
  1779.     }
  1780. }
  1781.